<!DOCTYPE html>
<html lang="zh-CN">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<link rel="stylesheet" href="./bootstrap/css/bootstrap.min.css">
	<style>
		.null-value {
			font-style: italic;
			color: #a3d6da!important;
		}
		.null-value span {
			font-style: normal;
			color: white;
		}
		.my-container {
			display: flex;
			justify-content: center;
		}
		#coreDiv {
			min-width: 50%;
		}
		.getPosition {
			width: 470px;
		}
		#tmpArea {
			position: fixed;
			margin-top: 123px;
			margin-left: 10px;
		}

	</style>
	<script src="./jquery/jquery.min.js"></script>
	<script src="./bootstrap/js/bootstrap.min.js"></script>
</head>

<body>
	<div class="my-container">
		<div id="coreDiv">
			<h2 id="tableNameTag" style="margin-top: 15px;"></h2>
			<button type="button" class="btn btn-primary" onclick="onAddRecordBtnClick()">插入记录</button> &nbsp;
			<button type="button" class="btn btn-success" onclick="backToIndex()">返回数据表页</button>
			<br>
			<br>
			<table class="table table-striped table-dark">
				<thead id="detailTHead">
				</thead>
				<tbody id="detailTBody">
				</tbody>
			</table>
		</div>
		<div id="getPosition">
			<div id="tmpArea"></div>
		</div>
	</div>
</body>

<script>
	var typeRegexMap = {
		int : /[0-9]+/,
		varchar: /.*/,
		date: /^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$/
	}

	var commonUtil = {
		/**
		 * 弹出消息框
		 * @param msg 消息内容
		 * @param type 消息框类型（参考bootstrap的alert）
		 */
		alert: function(msg, type){
			if(typeof(type) =="undefined") { // 未传入type则默认为success类型的消息框
			type = "success";
			}
			// 创建bootstrap的alert元素
			var divElement = $(`<div style="margin: auto"></div>`).addClass('alert').addClass('alert-'+type).addClass('alert-dismissible').addClass('col-md-4').addClass('col-md-offset-4');
			divElement.css({ // 消息框的定位样式
			"position": "fixed",
			"top": "40px",
			"left":"0",
			"right":"0",
			"margin":"auto"
			});
			divElement.text(msg); // 设置消息框的内容
			// 消息框添加可以关闭按钮
			var closeBtn = $('<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>');
			$(divElement).append(closeBtn);
			// 消息框放入到页面中
			$('body').append(divElement);
			return divElement;
		},
		
		/**
		 * 短暂显示后上浮消失的消息框
		 * @param msg 消息内容
		 * @param type 消息框类型
		 */
		message: function(msg, type) {
			var divElement = commonUtil.alert(msg, type); // 生成Alert消息框
			var isIn = false; // 鼠标是否在消息框中
			
			divElement.on({ // 在setTimeout执行之前先判定鼠标是否在消息框中
			　　mouseover : function(){isIn = true;},
			　　mouseout : function(){isIn = false;}
			});

			// 短暂延时后上浮消失
			setTimeout(function() {
			var IntervalMS = 20; // 每次上浮的间隔毫秒
			var floatSpace = 20; // 上浮的空间(px)
			var nowTop = window.getComputedStyle(divElement[0]).top; // 获取元素当前的top值
			var reg = /(.*)px/;
			nowTop = parseInt(reg.exec(nowTop)[1]);
			var stopTop = nowTop - floatSpace;  // 上浮停止时的top值
			divElement.fadeOut(IntervalMS * floatSpace); // 设置元素淡出
			
			var upFloat = setInterval(function(){ // 开始上浮
				if (nowTop >= stopTop) { // 判断当前消息框top是否还在可上升的范围内
				divElement.css({"top": nowTop--}); // 消息框的top上升1px
				} else {
				clearInterval(upFloat); // 关闭上浮
				divElement.remove();  // 移除元素
				}
			}, IntervalMS);

			if (isIn) { // 如果鼠标在setTimeout之前已经放在的消息框中，则停止上浮
				clearInterval(upFloat);
				divElement.stop();
			}
			
			divElement.hover(function() { // 鼠标悬浮时停止上浮和淡出效果，过后恢复
				clearInterval(upFloat);
				divElement.stop();
			},function() {
				divElement.fadeOut(IntervalMS * (nowTop - stopTop)); // 这里设置元素淡出的时间应该为：间隔毫秒*剩余可以上浮空间
				upFloat = setInterval(function(){ // 继续上浮
				if (nowTop >= stopTop) {
					divElement.css({"top": nowTop--});
				} else {
					clearInterval(upFloat); // 关闭上浮
					divElement.remove();  // 移除元素
				}
				}, IntervalMS);
			});
			}, 600);
		}
	}

	var dataBaseTableData = null;
	function showTableDetail(data) {
		var tableNameTag = document.getElementById("tableNameTag");
		tableNameTag.innerHTML = tableName;

		var thead = document.getElementById("detailTHead");
		var tHeadInner = "";
		var fields = data["fields"];
		tHeadInner += `<tr>`;
		for (let i = 0; i < fields.length; i++) {
			tHeadInner += `<th scope="col">${fields[i]["Field"]}</th>`
		}
		tHeadInner += `<th scope="col">操作</th>`
		tHeadInner += `</tr>`;
		thead.innerHTML = tHeadInner;

		var keyField = data["keyField"];
		var tbody = document.getElementById("detailTBody");
		var tBodyInner = "";
		var detailData = data["detailData"];
		for (let i = 0; i < detailData.length; i++) {
			var oneRecord = detailData[i];
			tBodyInner += `<tr>`;
			var keyFieldVal = null;
			for (let j = 0; j < fields.length; j++) {
				var field = fields[j];
				var value = oneRecord[field["Field"]];
				if(value === null) {
					tBodyInner += `<td class="null-value" ondblclick=itemDoubleClick(this) listen="true" index="${j}">(${value})</td>`;
				}
				else {
					tBodyInner += `<td ondblclick=itemDoubleClick(this) listen="true" index="${j}">${value}</td>`;
				}
				
				if (field["Field"] == keyField) {
					// 获取主键的值
					keyFieldVal = oneRecord[field["Field"]];
				}
			}
			tBodyInner += `
			<td keyfieldval="${keyFieldVal}">
				<button type="button" class="btn btn-danger" onclick="onDeleteBtnClick(${keyFieldVal})">删除</button>
				<button type="button" class="btn btn-info" onclick="onModifyBtnClick(${keyFieldVal}, this)">修改</button>
			</td>`;
			tBodyInner += `</tr>`;
		}
		tbody.innerHTML = tBodyInner;
	}

	function tmpCheckboxClick(checkbox) {
		var tmpInput = document.getElementById("tmpInput");
		var isReadonly = tmpInput.getAttribute("readonly");
		if(isReadonly == "true") {
			tmpInput.removeAttribute("readonly");
		}
		else {
			tmpInput.setAttribute("readonly", "true");
		}
	}

	var tmpInputOriginVal = "";
	var checkStat = null;
	function itemDoubleClick(item) {
		if(item.getAttribute("listen") == "false") {
			return;
		}
		item.setAttribute("listen", "false");
		var originVal = item.innerHTML;
		
		item.innerHTML = `
		<input class="form-control" id="tmpInput" style="height: ${item.offsetHeight * 0.5}px; width: ${item.offsetWidth * 1.0}px;" value="${originVal}">
		<input type="checkbox" id="tmpCheckbox" onclick="tmpCheckboxClick(this)"><span>Null</span>
		`;
		var input = item.children[0];
		tmpInputOriginVal = input["value"];
		if(item.getAttribute("class") === "null-value") {
			document.getElementById("tmpCheckbox").click();
		}
		checkStat = item.children[1].checked;
		input.focus();
		$("#tmpInput").keydown(function(event){
			if(event.keyCode==13){
				// console.log('你按下了Enter');
				modifyBlur(input);
			}
		});
		$("#tmpCheckbox").keydown(function(event){
			if(event.keyCode==13){
				modifyBlur(input);
			}
		});
	}

	function modifyBlur(input) {
		var resValue = input["value"];
		var td = input.parentNode;
		var nullCheckbox = document.getElementById("tmpCheckbox");
		// 若没有发生修改则直接返回
		if(nullCheckbox.checked == checkStat && tmpInputOriginVal == resValue) {
			td.innerHTML = resValue;
			td.setAttribute("listen", "true");
			return;
		}
		if(nullCheckbox.checked) {
			resValue = null;
		}

		var fieldIndex = td.getAttribute("index");
		var fields = dataBaseTableData["fields"];
		var uploadObject = {};
		uploadObject[fields[fieldIndex]["Field"]] = resValue;

		var tr = td.parentNode;
		var lastTd = tr.children[tr.children.length-1];
		var priKey = lastTd.getAttribute("keyfieldval");
		$.ajax({
			url: "/exp3/DataController.php",
			type: "post",
			data: JSON.stringify({
				option: "modify",
				id: priKey,
				tableName: tableName,
				object: uploadObject
			}),
			success: function (retData) {
				console.log(retData);
				updateDataShow();
				commonUtil.message("修改成功！");
			}
		})
		td.innerHTML = resValue;
		td.setAttribute("listen", "true");
	}

	function tmpAreaAddTable() {
		// $("#getPosition").removeClass("container");
		$("#getPosition").addClass("getPosition");
		var tmpArea = document.getElementById("tmpArea");
		var fields = dataBaseTableData["fields"];
		var tmpAreaInner = "";
		tmpAreaInner +=  `<table class="table table-striped table-sm">`;
		tmpAreaInner += 
		`<thead>
            <tr>
                <th>字段</th>
                <th>类型</th>
                <th>值</th>
                <th>是否为null</th>
            </tr>
        </thead>`;

		tmpAreaInner +=	`<tbody>`;
		for (let i = 0; i < fields.length; i++) {
			var field = fields[i];
			tmpAreaInner += 
			`<tr>
				<td>${field["Field"]}</td>
				<td>${field["Type"]}</td>
				<td><input type="text" name="${field["Field"]}" class="form-control upLoadOjbect" placeholder="${fields[i]["Field"]}"></td>
				<td><input type="checkbox" class="isNullCheckBoxes" onclick="onIsNullCheckboxClick(this)"></td>
			</tr>`;
		}
		tmpAreaInner += `</tbody></table>`;
		tmpArea.innerHTML = tmpAreaInner;
	}

	function onIsNullCheckboxClick(checkbox) {
		var textInput = checkbox.parentNode.parentNode.children[2].children[0];
		var isReadonly = textInput.getAttribute("readonly");
		if(isReadonly == "true") {
			textInput.removeAttribute("readonly");
		}
		else {
			textInput.setAttribute("readonly", "true");
		}
	}

	function onAddRecordBtnClick() {
		var tmpArea = document.getElementById("tmpArea");
		tmpAreaAddTable();

		tmpArea.innerHTML += `
		&nbsp&nbsp<button type="button" class="btn btn-primary mb-2" onclick="confirmAddRecord()">确定添加</button>
		<button type="button" class="btn btn-success mb-2" onclick="back()">返回</button>
		`;
	}

	function confirmAddRecord() {
		var inputs = document.getElementsByClassName("upLoadOjbect");
		var checkboxes = document.getElementsByClassName("isNullCheckBoxes");
		var uploadObject = {};
		for (var i = 0; i < inputs.length; i++) {
			var oneInput = inputs[i];
			if(checkboxes[i].checked) {
				uploadObject[oneInput["name"]] = null;
			}
			else {
				uploadObject[oneInput["name"]] = oneInput["value"];
			}
		}

		// console.log(uploadObject);
		$.ajax({
			url: "/exp3/DataController.php",
			type: "post",
			data: JSON.stringify({
				option: "newRecord",
				tableName: tableName,
				object: uploadObject
			}),
			contentType: 'application/json',
			success: function (retData) {
				console.log(retData);
				updateDataShow();
				commonUtil.message("数据插入成功！");
			}
		})
	}

	function back() {
		$("#getPosition").removeClass("getPosition");
		// $("#coreDiv").addClass("container");
		var tmpArea = document.getElementById("tmpArea");
		tmpArea.innerHTML = "";
	}

	function updateDataShow() {
		$.ajax({
			url: "/exp3/DataController.php",
			data: {
				tableName: tableName,
				option: "get",
				type: "list"
			},
			async: false,
			success: function (retData) {
				var data = eval('(' + retData + ')');
				dataBaseTableData = data;
				showTableDetail(data);
			}
		})
	}

	function onDeleteBtnClick(priKey) {
		if(confirm("您确定要删除该记录吗？")) {
			$.ajax({
				url: "/exp3/DataController.php",
				data: {
					tableName: tableName,
					option: "delete",
					id: priKey
				},
				success: function (retData) {
					console.log(retData);
					updateDataShow();
					commonUtil.message("删除成功！");
				}
			})
		}
	}

	function onModifyBtnClick(priKey, btn) {
		$.ajax({
			url: "/exp3/DataController.php",
			type: "get",
			async: false,
			data: {
			    tableName: tableName,
			    option: "get",
			    type: "single",
				id: priKey
			},
			success: function(retData) {
				var data = eval('(' + retData + ')');

				var tmpArea = document.getElementById("tmpArea");
				tmpAreaAddTable();
				var inputs = document.getElementsByClassName("upLoadOjbect");
				var checkboxes = document.getElementsByClassName("isNullCheckBoxes");

				var fields = dataBaseTableData["fields"];
				for (let i = 0; i < fields.length; i++) {
					var field = fields[i];
					var oneInput = inputs[i];
					var value = data[field["Field"]];
					if(value !== null) {
						oneInput.setAttribute("value", data[field["Field"]]);
					}
					else {
						oneInput.setAttribute("readonly", "true");
						checkboxes[i].setAttribute("checked", "checked");
					}
					if(fields[i]["Key"]=="PRI") {
						oneInput.setAttribute("readonly", "true");
						checkboxes[i].setAttribute("disabled", "true");
					}
				}
				tmpArea.innerHTML += `
				&nbsp&nbsp<button type="button" class="btn btn-info mb-2" onclick="confirmModify(${priKey})">确定修改</button> 
				<button type="button" class="btn btn-success mb-2" onclick="back()">返回</button>
				`;
			}
		});
	}

	function confirmModify(priKey) {
		var inputs = document.getElementsByClassName("upLoadOjbect");
		var checkboxes = document.getElementsByClassName("isNullCheckBoxes");
		var uploadObject = {};
		for (var i = 0; i < inputs.length; i++) {
			var oneInput = inputs[i];
			if(checkboxes[i].checked) {
				uploadObject[oneInput["name"]] = null;
			}
			else {
				uploadObject[oneInput["name"]] = oneInput["value"];
			}
		}

		if(confirm("您确认要进行当前修改吗？")){
				$.ajax({
				url: "/exp3/DataController.php",
				type: "post",
				data: JSON.stringify({
					option: "modify",
					id: priKey,
					tableName: tableName,
					object: uploadObject
				}),
				success: function (retData) {
					console.log(retData);
					updateDataShow();
					commonUtil.message("修改成功！");
				}
			})
		}
	}

	function backToIndex() {
		window.location.href = "/exp3/index.html";
	}

	var $_GET = (function () {
		var url = window.document.location.href.toString();
		var u = url.split("?");
		if (typeof (u[1]) == "string") {
			u = u[1].split("&");
			var get = {};
			for (var i in u) {
				var j = u[i].split("=");
				get[j[0]] = j[1];
			}
			return get;
		} else {
			return {};
		}
	})();
	var tableName = $_GET["tableName"];
	updateDataShow();
</script>

</html>